home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-02
/
tptc16.zip
/
TPTC.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1993-01-04
|
14KB
|
466 lines
(*
todo:
-- in var params, passing address of pointer
-- two dimensional arrays, typed constants, see test.pas
-- array[a,b...] and array[a] of array... not translated
-- process subscripted (full lvalue) for fd's in read/write
-- translate 'str' and 'val'
-- string returning procedures translated to char * return
-- string (pointer to array) var parameters translated to char *
-- pointer deref does not determine lvalue type (i.e. xxx->m should
detect string types)
-- writeln strings: 'literal',^M^J,'another'
-- nested variable sharing not proper
procedure ordering
outer local decl's not prefixed
-- variant records not translated
-- untyped parameter variables
-- absolute variables
manual translations:
-- nested procedure ordering
-- atoi macro clash ?
changes
-- turbo-c procedure declaration syntax
-- arrays subscripted by enumeration types
-- fails to handle null else clause in case statement
-- include intermediate cases in swith() .. case x..y
-- pointer/var parameter translation *id.mem should be id->mem
-- pointer/var parameter translation *id[n] should be id[n]
-- concat(...)+char and string+char not detected as string/character
concat operation.
-- detect concat(concat... and replace with a sprintf variant
-- changed sprintf calls to sbld calls to preserve sources during build
-- pos(c,str) and pos(str,str) are now separately translated
-- added 'base' to symbol table; use to add base-subscript offset
in all subscript references.
-- moved typename translations to tpcmac.h header
-- fixed bug in non-translation of tshell directives
-- forward pointer declarations
-- translate inline into asm statements
-- complete forward translation
---------------
13-oct-87
-- improved string and array parameter translations
-- string returns are now translated into char *
15-oct-87
-- corrected error in typed constant translation where nested
records are initialized.
-- variant record declarations are translated into unions
but no variant expression translations are done.
-- changed nested procedure error messages to include procedure name.
(*
*
* TPTC - Turbo Pascal to C translator
*
* S.H.Smith, 9/9/85 (rev. 2/13/88)
*
* Copyright 1986, 1987 by Samuel H. Smith; All rights reserved.
*
*
* Revision history
* ----------------
*
* 09/09/85 v0.0 (paspp)
* Initial coding by Samuel H. Smith. Never released.
*
* 12/19/86 v1.0
* First distributed as TPC10 under shareware concept.
*
* 04/15/87 v1.1
* Corrected handling of unary minus.
* Improved error messages; added error messages to object file.
* Added handler for integer subrange types.
* Added handling for goto statement and numeric labels.
* The macro header, tpcmac.h, now contains more declarations.
* Distributed as TPC11.
*
* 04/22/87 v1.2
* Corrected an error that led to a crash on lines with more than 40
* leading spaces. Distributed as TPC12.
*
* 05/20/87 v1.3
* Added support for pascal/MT+: external procedures and variables,
* special write/read indirect syntax, & and ! operators,
* default string size for string declarations.
* Distributed as TPC13.
*
* 05/26/87 v1.4
* Additional support for pascal/MT+. The translator "shifts" into a
* MT+ specific mode when it recognizes the 'MODULE' statement.
* The '|' operator is recognized for bitwise OR.
* The '\', '?' and '~' operators are all translated into a unary
* not (is this right, Noam?).
* Read(ln) and Write(ln) now support the special case of "[]" for the
* I/O routine.
* Long integer literals are translated from '#nnn' to 'nnnL'
*
* 06/01/87 v1.5
* Added new ','nd-line parser.
* Added -lower option to map identifiers to lower case.
* Added -mt option to force pascal/mt+ mode.
* Added partial var-parameter translation.
* Mem, MemW, Port and PortW are all translated into Turbo C.
* Turbo-c procedure declaration syntax is now used.
* Arrays may now be subscripted by enumeration types.
* Null else clause now handled properly in IF and CASE statements.
* For .. downto is now translated correctly.
* The VAL..VAL form is now translated in case statements.
*
*)
{$R+} {Range checking off}
{$B+} {Boolean complete evaluation on}
{$S+} {Stack checking on}
{$I+} {I/O checking on}
{$N-} {No numeric coprocessor}
{$V-} {Relax string rules}
{$M 65500,16384,655360} {Turbo 3 default stack and heap}
program translate_tp_to_c;
uses Crt;
const
version1 = 'TPTC - Translate Pascal to C';
version2 = 'Version 1.6, 2/8/88 S.H.Smith';
maxparam = 20; {max number of parameters to process}
identlen = 12; {nominal length of identifiers}
maxnest = 6; {maximum procedure nesting}
nestfile = 'nest$'; {scratchfile for nested procedures}
localseprt = '__S__'; {local sym table nesting separating string}
type
anystring = string [127];
string255 = string [255];
string80 = string [80];
string40 = string [40];
string20 = string [20];
string10 = string [10];
toktypes = (number, identifier,
strng, keyword,
unknown);
symtypes = (s_int, s_long,
s_double, s_string,
s_char, s_struct,
s_file, s_void );
supertypes = (ss_scalar, ss_const,
ss_func, ss_struct,
ss_array );
symptr = ^symrec;
symrec = record
symtype: symtypes; { simple type }
suptype: supertypes; { scalar,array etc. }
id: string40; { name of entry }
parcount: integer; { parameter count }
pvar: integer; { var/val reference }
base: integer; { base value for subscripts }
limit: integer; { limiting value for scalars }
parent: symptr;
next: symptr;
end;
paramlist = record
n: integer;
id: array [1..maxparam] of string80;
stype: array [1..maxparam] of symtypes;
sstype: array [1..maxparam] of supertypes;
end;
const
(* names of symbol types *)
typename: array[symtypes] of string40 =
('int', 'long',
'double', 'char *',
'char', 'struct',
'file', 'void');
supertypename: array[supertypes] of string40 =
('Scalar', 'Constant',
'Function', 'Structure',
'Array' );
(* these words start new statements or program sections *)
nkeywords = 12;
keywords: array[1..nkeywords] of string40 = (
'PROGRAM', 'PROCEDURE', 'FUNCTION',
'VAR', 'CONST', 'TYPE',
'LABEL', 'OVERLAY', 'FORWARD',
'MODULE', 'EXTERNAL', 'CASE');
var
con: text;
ltok: string80;
tok: string80;
toktype: toktypes;
infd: text;
inclfd: text;
incl_name: string[64];
read_include: boolean;
nextc: char;
spaces: anystring;
extradot: boolean;
nospace: boolean;
unitlevel: integer;
globals: symptr;
locals: symptr;
curtype: symtypes;
cursuptype: supertypes;
curlimit: integer;
srclines: array [1..maxnest] of integer;
srcfiles: array [1..maxnest] of string40;
ofd: array[1..maxnest] of text;
level: integer;
in_locals: boolean;
past_marker: boolean;
in_globals: boolean;
nestn: string10;
mt_plus: boolean; {true if translating Pascal/MT+}
map_lower: boolean; {true to map idents to lower case}
dumpsymbols: boolean; {dump tables to object file}
includeinclude:boolean; {include include files in output}
{$I \tinc\ljust.inc} {left justify writeln strings}
{$I \tinc\atoi.inc} {ascii to integer conversion}
{$I \tinc\ftoa.inc} {float to ascii conversion}
{$I \tinc\stoupper.inc} {map string to upper case}
procedure gettok; forward;
procedure pblock; forward;
procedure pstatement; forward;
procedure punit; forward;
procedure pvar; forward;
function plvalue: string255; forward;
function pexpr: string255; forward;
procedure pident; forward;
procedure exit_nested; forward;
procedure enter_nested; forward;
procedure discard_nested; forward;
(********************************************************************)
{$I tpcsym.inc} {symbol table handler}
{$I tpcmisc.inc} {misc functions}
{$I tpcscan.inc} {scanner; lexical analysis}
{$I tpcexpr.inc} {expression parser and translator}
{$I tpcstmt.inc} {statement parser and translator}
{$I tpcdecl.inc} {declaration parser and translator}
{$I tpcunit.inc} {program unit parser and translator}
(********************************************************************)
procedure init;
{initializations before translation can begin}
procedure enter(name: anystring; etype: symtypes);
begin
newsym(name, etype, ss_scalar, -1, 0, 0);
end;
begin
spaces := '';
nospace := false;
ltok := '';
tok := '';
toktype := unknown;
extradot := false;
srclines[level] := 0;
unitlevel := 0;
globals := nil;
locals := nil;
curtype := s_void;
cursuptype := ss_scalar;
read_include := false;
nestn := '00';
newsym('argv', s_string, ss_array, -1, 0, 0);
enter('argc', s_int);
enter('con', s_file);
enter('kbd', s_file);
enter('lst', s_file);
enter('output',s_file);
enter('input', s_file);
enter('aux', s_file);
end;
(********************************************************************)
procedure usage(why: anystring);
{print usage instructions and copyright}
begin
writeln('Copyright 1986, 1987 by Samuel H. Smith; All rights reserved.');
writeln;
writeln('Please refer all inquiries to:');
writeln(' Samuel H. Smith The Tool Shop BBS');
writeln(' 5119 N 11 Ave 332 (602) 279-2673');
writeln(' Phoenix, AZ 85013');
writeln;
writeln('You may copy and distribute this program freely, provided that:');
writeln(' 1) No fee is charged for such copying and distribution, and');
writeln(' 2) It is distributed ONLY in its original, unmodified state.');
writeln;
writeln('If you like this program, and find it of use, then your contribution');
writeln('will be appreciated. If you are using this product in a commercial');
writeln('environment then the contribution is not voluntary.');
writeln;
write('Press enter: ');
readln;
writeln;
writeln;
writeln('Error: ',why);
writeln;
writeln(
'Usage: TPTC input_file [output_file] [-lower] [-mt] [-dump] [-include]');
writeln;
writeln('Where:');
writeln(' input_file specifies the main source file, .PAS default');
writeln(' output_file specifies the output file, .C default');
writeln(' -lower map all identifiers to lower case');
writeln(' -mt use Pascal/MT+ specific translations');
writeln(' -dump Dump symbols');
writeln(' -include output include files'' contents');
writeln;
writeln('Example:');
writeln(' tptc fmap -lower -dump');
writeln;
halt;
end;
(* main program *)
var
inname: anystring;
outname: anystring;
par: anystring;
i: integer;
begin
assign(con,'');
rewrite(con);
writeln(con);
writeln(con,version1);
writeln(con,' ',version2);
writeln(con);
(* get command line options, if any *)
outname := '';
inname := '';
map_lower := false;
mt_plus := false;
dumpsymbols := false;
includeinclude := false;
for i := 1 to paramcount do
begin
par := paramstr(i);
if par[1] = '-' then
begin
if par = '-lower' then
map_lower := true
else
if par = '-mt' then
mt_plus := true
else
if par = '-dump' then
dumpsymbols := true
else
if par = '-include' then
includeinclude := true
else
usage('invalid option');
end
else
if inname = '' then
inname := par
else
if outname = '' then
outname := par
else
usage('duplicate input/output name');
end;
if inname = '' then
usage('missing input name');
if outname = '' then
outname := inname;
if pos('.',inname) = 0 then
inname := inname + '.pas';
if inname = outname then
usage('duplicate input/output name');
assign(infd,inname);
srcfiles[1] := inname;
{$I-} reset(infd); {$I+}
if ioresult <> 0 then
begin
writeln(con,'Can''t open input file: ',inname);
halt;
end;
if pos('.',outname) = 0 then
outname := outname + '.c';
level := 1;
assign(ofd[level],outname);
{$I-}
rewrite(ofd[level]);
{$I+}
if ioresult <> 0 then
begin
writeln(con,'Can''t open output file: ',outname);
halt;
end;
(* do initializations *)
init;
(* process the source file(s) *)
pprogram;
purgetable(globals);
writeln(con,srclines[level]' lines ');
close(ofd[level]);
end.